package wci.frontend.pascal.parsers;

import java.util.EnumSet;

import wci.frontend.*;
import wci.frontend.pascal.*;
import wci.intermediate.*;
import wci.intermediate.icodeimpl.*;

import static wci.frontend.pascal.PascalTokenType.*;
import static wci.frontend.pascal.PascalErrorCode.*;
import static wci.intermediate.icodeimpl.ICodeNodeTypeImpl.*;
import static wci.intermediate.icodeimpl.ICodeKeyImpl.*;

/**
 * <h1>WhileStatementParser</h1>
 * <p>解析 Pascal WHILE 语句，包含普通的WHILE</p>
 * <p>Copyright (c) 2009 by Ronald Mak</p>
 * <p>For instructional purposes only.  No warranties.</p>
 */
public class WhileStatementParser extends StatementParser
{
    public WhileStatementParser(PascalParserTD parent)
    {
        super(parent);
    }

    //DO同步集合
    private static final EnumSet<PascalTokenType> DO_SET =
        StatementParser.STMT_START_SET.clone();
    static {
        DO_SET.add(DO);
        DO_SET.addAll(StatementParser.STMT_FOLLOW_SET);
    }
    public ICodeNode parse(Token token)
        throws Exception
    {
    	//干掉语句开始的WHILE
        token = nextToken(); 
        ICodeNode loopNode = ICodeFactory.createICodeNode(LOOP);
        ICodeNode breakNode = ICodeFactory.createICodeNode(TEST);
        //这个父节点肯定是breakNode，参见图7-4
        ICodeNode notNode = ICodeFactory.createICodeNode(ICodeNodeTypeImpl.NOT);
        loopNode.addChild(breakNode);
        breakNode.addChild(notNode);
        // 退出测试表达式
        ExpressionParser expressionParser = new ExpressionParser(this);
        notNode.addChild(expressionParser.parse(token));
        // 表达式之后的DO或其它，比如 while a>b;
        token = synchronize(DO_SET);
        if (token.getType() == DO) {
            token = nextToken();  
        }
        else {
            errorHandler.flag(token, MISSING_DO, this);
        }
        //循环语句主体，只有一条语句
        StatementParser statementParser = new StatementParser(this);
        loopNode.addChild(statementParser.parse(token));
        return loopNode;
    }
}
